/*
	// http://blog.csdn.net/zg_hover/article/details/2553321
	守护进程实例
　　守护进程实例包括两部分：主程序test.c和初始化程序init.c。
    主程序每隔一分钟向/tmp目录中的日志test.log报告运行状态。
    初始化程序中的init_daemon函数负责生成守护进程。读者可以利用init_daemon函数生成自己的守护进程。`
*/

#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

// init.c
void init_daemon(void) {
	int pid;
	int i;
	
	if(pid=fork())
		exit(0);	// 是父进程，结束父进程
	else if(pid < 0)
		exit(1);	// fork失败，退出
	
	// 是地一个子进程，后台继续执行
	setsid();	// 第一紫禁城成为新的会话组长和进程组长
	// 并与控制终端分离
	if(pid=fork())
		exit(0);	// 是第一个子进程，结束第一子进程
	else if(pid < 0)
		exit(1);	// fork 失败，退出

	// 是第二个紫禁城，继续
	// 第二个子进程不再是会话组长
	for(i=0; i<NOFILE; ++i)	// 关闭打开的文件描述符
		close(i);

	chdir("/tmp");	// 改变工作目录到/tmp
	umask(0);		// 重设文件创建掩膜

	return ;
}

int main(int argc, char * argv[]) {
	FILE * fp;
	time_t t;
	init_daemon(); // 初始化为Daemon

	// 每隔一分钟向test.log报告运行状态
	while(1) {
		sleep(60);
		if((fp=fopen("test.log", "a")) >= 0) {
			t = time(0);
			fprintf(fp, "I'm here at %s\n", asctime(localtime(&t)));
			fclose(fp);
		}
	}

	return 0;
}
